package edu.hawaii.halealohacli;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import org.wattdepot.client.WattDepotClient;
import edu.hawaii.halealohacli.command.RepeatedCommand;
import edu.hawaii.halealohacli.processor.QueryProcessor;

/**
 * A command line interface program for energy queries on the the Hale Aloha Towers server.
 * 
 * @author Leo deCandia
 * @author Jeffery M. Beck
 * @author Zach Tomaszewski
 */
public class HaleAlohaCli {

  /** The URL of the WattDepot server that this CLI connects too. */
  public static final String URL = "http://server.wattdepot.org:8190/wattdepot/";

  /** The query processor. */
  QueryProcessor queryProcessor;
  
  
  /**
   * Parses the input line.
   * 
   * @param inputLine the last input line entered by the user
   * @return all the tokens parsed from the input line
   */
  private String[] parseInputLine(String inputLine) {
    String delims = "[ ]+";
    return inputLine.trim().split(delims);
  }
  
  /**
   * Answer query.
   * 
   * @param curLine the line entered by the user
   */
  private void answerQuery(String curLine) {
    String[] words = parseInputLine(curLine);
    if (words != null && words.length > 0 && words[0] != null) {
      int length = words.length;
      String[] args = new String[length - 1];
      System.arraycopy(words, 1, args, 0, length - 1);
      if (queryProcessor.getUsageDictionary().containsKey(words[0])) {
        //valid command
        queryProcessor.invokeCommandByName(words[0], args);
        System.out.println();
      }
      else if ("help".equals(words[0])) {
        printUsageInfo();
      }
      else if ("".equals(words[0])) {  //NOPMD: empty if case
        //entered nothing, so just ignore it                 
      }
      else {
        System.out.println("'" + words[0] + "'" + " is not a command!\n");
      }
    }
  }

  /**
   * Prints the usage info for each Command class found.
   */
  private void printUsageInfo() {
    System.out.println("\nAvailable commands are:\n\n");
    Map<String, String> dictionary = queryProcessor.getUsageDictionary();
    for (Map.Entry<String, String> entry : dictionary.entrySet()) {
      if (entry.getKey().equals("fake-command")) {
        continue;
      }
      String usageInfo = entry.getValue() == null ? "" : entry.getValue();
      System.out.println(usageInfo);
    }
  }

  /**
   * Prints commands for the Command classes found.
   */
  private void printCommandsfound() {
    System.out.println("Looking for commands....");
    Map<String, String> dictionary = queryProcessor.getUsageDictionary();
    for (Map.Entry<String, String> entry : dictionary.entrySet()) {
      if (!entry.getKey().equals("fake-command")) {
        System.out.println("Found command: " + entry.getKey());
      }
    }
  }

  /**
   * Answer queries.
   */
  private void answerQueries() {
    String curLine = ""; // Line read from standard in

    InputStreamReader converter = new InputStreamReader(System.in);
    BufferedReader in = new BufferedReader(converter);

    while (!("quit".equals(curLine))) {
      try {
        System.out.print("Enter a command: > ");
        curLine = in.readLine();
        if ("quit".equals(curLine)) {
          System.out.println("quitting...");
          break;
        }
        if (curLine != null && !("quit".equals(curLine))) {
          answerQuery(curLine);
        }
      }
      catch (IOException e) {
        e.printStackTrace();
        System.out.println("Exiting!");
      }
    }
  }

  /**
   * The main method.
   * 
   * @param args no arguments expected
   */
  public static void main(String[] args) {
    System.out.println("Welcome to hale-aloha-cli-grads");
    
    // Create a client.
    WattDepotClient client = new WattDepotClient(URL);
    // Check to make sure a connection can be made.
    // If no connection, then exit right now.
    if (!client.isHealthy()) {
      System.out.format("Could not connect to: %s%n", URL);
      return;
    }

    System.out.format("Server: %s%n", URL);
    System.out.println("Type help for a list of possible commands.");
    System.out.println();

    HaleAlohaCli cli = new HaleAlohaCli();
    cli.queryProcessor = new QueryProcessor(client);

    // commented out JB
    // cli.printCommandsfound();
    
    cli.answerQueries();
    RepeatedCommand.terminateAll();
  }
}
